# 一个函数可以同时被多个装饰器装饰，此时装饰器的应用顺序是从下往上（即离被装饰函数定义最近的装饰器先应用），但执行顺序是从上往下（即最上面的装饰器对应的包装函数先执行）。
def decorator1(func):
    def wrapper1(*args, **kwargs):
        print('wrapper1-begin')
        func(*args, **kwargs)
        print('wrapper1-after')

    return wrapper1


def decorator2(func):
    def wrapper2(*args, **kwargs):
        print('wrapper2-begin')
        func(*args, **kwargs)
        print('wrapper2-after')

    return wrapper2


@decorator1
@decorator2
def test(a, b):
    result = a + b
    print(f'{a} + {b} = {result}')


test(2, 3)
